﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using FulcrumApi.entities;
using HtmlAgilityPack;
using HttpClient;
using Newtonsoft.Json;

namespace FulcrumApi.clients
{
    public class FulcrumHttpClient
    {
        public String authenticityToken;
        private String host;
        private HTTPClient client = new DefaultHttpClient();

        public FulcrumHttpClient(String host)
        {
            this.host = host;
            authenticityToken = extractAuthenticityToken();
        }

        public String extractAuthenticityToken()
        {
            var content = doGet("", new Dictionary<String, String>());
            HtmlDocument doc = new HtmlDocument();
             doc.Load(content);
             foreach(HtmlNode meta in doc.DocumentNode.SelectNodes("//meta[@name='csrf-token']"))
             {
                return meta.Attributes["content"].Value;
             }
            throw new Exception("Token not found");
        }

        public Stream doPost(String uri, Dictionary<String, String> parameters) {
		    String requestUrl = host + uri;
            parameters.Add("authenticity_token", authenticityToken);
            var resp = HttpHelper.Post(requestUrl, parameters, authenticityToken, client);
            if (!isResponseOk(resp))
            {
                throw new Exception("");
            }
            return resp.Response;
        }

        public Stream doDelete(String uri, Dictionary<String, String> parameters)
        {
            String requestUrl = host + uri;
            parameters.Add("authenticity_token", authenticityToken);
            var resp = HttpHelper.Delete(requestUrl, parameters, authenticityToken, client);
            if (!isResponseOk(resp))
            {
                throw new Exception("");
            }
            return resp.Response;
        }

        public Stream doPost(String uri, Object body)
        {
            String requestUrl = host + uri;
            var sb = JsonConvert.SerializeObject(body);
            var resp = HttpHelper.PostJson(requestUrl, sb, authenticityToken, client);
            if (!isResponseOk(resp))
            {
                throw new Exception("");
            }
            return resp.Response;
        }

        public Stream doGet(String uri, Dictionary<String, String> parameters)
        {
            var resp = HttpHelper.Get(host + uri, parameters, authenticityToken, client);
            if (!isResponseOk(resp))
            {
                throw new Exception("");
            }

            return resp.Response;
        }

        private bool isResponseOk(HttpWebResponse resp)
        {
            return resp.StatusCode == HttpStatusCode.OK ||
                   resp.StatusCode == HttpStatusCode.MovedPermanently ||
                   resp.StatusCode == HttpStatusCode.Created ||
                   resp.StatusCode == HttpStatusCode.NotAcceptable ||
                   resp.StatusCode == HttpStatusCode.Found;
        }

        private bool isResponseOk(HttpResponse resp)
        {
            return resp.StatusCode == HttpStatusCode.OK ||
                   resp.StatusCode == HttpStatusCode.MovedPermanently ||
                   resp.StatusCode == HttpStatusCode.Created ||
                   resp.StatusCode == HttpStatusCode.NotAcceptable ||
                   resp.StatusCode == HttpStatusCode.Found;
        }

        public void doDelete(String uri)
        {
            var parameters = new Dictionary<string, string>();
            parameters.Add("_method", "doDelete");
            doDelete(uri, parameters);
        }

        public String getAuthenticityToken()
        {
            return authenticityToken;
        }

        public Stream doPut(string uri, Object body)
        {
            String requestUrl = host + uri;
            var sb = JsonConvert.SerializeObject(body);
            var resp = HttpHelper.PutJson(requestUrl, sb, authenticityToken, client);
            if (!isResponseOk(resp))
            {
                throw new Exception("");
            }
            return resp.Response;
        }
    }
}
